package gameStates;

import java.util.concurrent.Callable;

import main.listeners.listenerClasses.GameListener;

import gameStates.passes.AbsPassManagerState;
import gameStates.passes.BasicGameStatePass;

import com.jme.renderer.pass.BasicPassManager;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.state.GameState;

/**
 * The basic class for all {@link GameState}s.
 * 
 * @author Wasserleiche
 */
public abstract class PassGameState extends SimpleGameState {
	
	/** The {@link Node} that contains all other {@link Spatial}s in this {@link GameState}. */
	protected Node rootNode;
	
	protected BasicGameStatePass pass;
	protected AbsPassManagerState passManagerState;
	
	public PassGameState(String stateName, AbsPassManagerState passManagerState) {
		this(stateName, passManagerState, false);
	}
	
	/**
	 * Creates a new SimpleGameState and initializes the rootNode.
	 * @param stateName The {@link GameState}-name.
	 */
	public PassGameState(String stateName, AbsPassManagerState passManagerState, boolean atEnd) {
		super(stateName);
		this.passManagerState = passManagerState;
				
		rootNode = new Node("Root Node");
		
		pass = new BasicGameStatePass();
		pass.setState(this);
		pass.setEnabled(false);
		passManagerState.addPass(pass);
		active = false;
				
		if(atEnd) {
			addListenerToClearer(new GameListener() {
				@Override
				public void gameStarted() {
					putAtEnd();
				}
				
				@Override
				public void gameFinished() {
					putAtEnd();
				}
				
				@Override
				public void gameDestroyed() {
					putAtEnd();
				}
			});
		}
	}
	
	public void putAtBeginning() {
		GameTaskQueueManager.getManager().update(new Callable<Void>() {
			@Override
			public Void call() throws Exception {
				BasicPassManager manager = passManagerState.getPassManager();
				manager.remove(pass);
				manager.insert(pass, 2);
				return null;
			}
		});
	}
	
	public void putAtEnd() {
		putAt(1);
	}
	
	public void putAtSecondEnd() {
		putAt(2);
	}
	
	public void putAt(final int pos) {
		GameTaskQueueManager.getManager().update(new Callable<Void>() {
			@Override
			public Void call() throws Exception {
				BasicPassManager manager = passManagerState.getPassManager();
				manager.remove(pass);
				manager.insert(pass, manager.passes() - pos);
				return null;
			}
		});
	}
	
	/**
	 * Returns the {@link Node} that contains all {@link Spatial}s to be displayed in this {@link GameState}.
	 * @return The rootNode of this {@link GameState}.
	 */
	public Node getRootNode() { return rootNode; }
	
	public BasicGameStatePass getPass() { return pass; }
	
	public void enableInput(boolean enable) {
		for(Controller c : rootNode.getControllers()) {
			c.setActive(enable);
		}
	}
	
	public void removeGameState() {
		GameTaskQueueManager.getManager().update(new Callable<Void>() {
			@Override
			public Void call() throws Exception {
				passManagerState.removePass(pass);
				return null;
			}
		});
	}
	
	@Override
	public void setActive(boolean active) {
		super.setActive(active);
		pass.setEnabled(active);
	}
	
	@Override
	public void cleanup() {
		super.cleanup();
		rootNode.detachAllChildren();
	}
	
	public AbsPassManagerState getPassManagerState() { return passManagerState; }
}